home *** CD-ROM | disk | FTP | other *** search
/ Aminet 49 / Aminet 49 (2002)(GTI - Schatztruhe)[!][Jun 2002].iso / Aminet / util / misc / ReportPlus.lha / ReportPlus / source / f10.c < prev    next >
C/C++ Source or Header  |  2002-04-16  |  44KB  |  1,259 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <intuition/intuition.h>
  4. #include <intuition/gadgetclass.h>
  5. #include <libraries/gadtools.h>
  6. #include <dos/dos.h>
  7. #include <dos/dostags.h>
  8. #include <dos/dosextens.h>
  9. #include <dos/exall.h>
  10. #include <dos/datetime.h>
  11. #include <graphics/gfx.h>
  12.  
  13. #include <clib/alib_protos.h>
  14. #include <clib/intuition_protos.h>
  15. #include <clib/graphics_protos.h>
  16. #include <clib/dos_protos.h>
  17. #include <clib/gadtools_protos.h>
  18. #include <clib/exec_protos.h>
  19.  
  20. #include <ctype.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "rp.h"
  24. #include "files.h"
  25.  
  26. #define ALL_REACTION_CLASSES
  27. #include <reaction/reaction.h>
  28.  
  29. #define DRIVELENGTH 4 // the length of the base drive path
  30.                       // (in this case, "SYS:")
  31.  
  32. MODULE void updatefiles(void);
  33. MODULE void stage1(void);
  34. MODULE void files_work(void);         // for stage1()
  35. MODULE void stage2(void);
  36. MODULE void dobuffer(ULONG whichpen); // for stage2()
  37. MODULE void stage3(void);
  38. MODULE void stopping(STRPTR status);
  39. MODULE void files_updatelog(void);
  40.  
  41. IMPORT ABOOL                ram;
  42. IMPORT SBYTE                page;
  43. IMPORT TEXT                 IOBuffer[LONGESTFIELD + 1],
  44.                             aslresult[MEDFIELD + 1];
  45. IMPORT ULONG                increment;
  46. IMPORT struct Screen*       ScreenPtr;
  47. IMPORT struct ExAllData*    EADataPtr;
  48. IMPORT struct VisualInfo*   VisualInfoPtr;
  49. IMPORT struct NewGadget     Gadget;
  50. IMPORT struct Menu*         MenuPtr;
  51. IMPORT Object*              WinObject[FUNCTIONS + 1];
  52. IMPORT struct Library     *ButtonBase,
  53.                           *CheckBoxBase,
  54.                           *ChooserBase,
  55.                           *IconBase,
  56.                           *LabelBase,
  57.                           *LayoutBase,
  58.                           *ListBrowserBase,
  59.                           *StringBase,
  60.                           *WindowBase;
  61.  
  62. AGLOBAL struct Gadget*      files_gadgets[GIDS_10 + 1];
  63.  
  64. MODULE struct List          DirList,
  65.                             FileList,
  66.                             FileDateList,
  67.                             FileTimeList,
  68.                             ResultList,
  69.                             EmptyResultList;
  70. MODULE ABOOL                ResultNodes      = FALSE,
  71.                             EmptyResultNodes = FALSE,
  72.                             build            = FALSE;
  73. MODULE ULONG                filesfound,
  74.                             status           = STATUS_READY;
  75. MODULE TEXT                 datestringholder[LEN_DATSTRING],
  76.                             timestringholder[LEN_DATSTRING];
  77. MODULE struct
  78. {   ULONG show[4]; // anything we want to use GetAttr() with must be ULONG
  79.     ULONG entries;
  80.     ULONG log, checkversion;
  81.     TEXT  pathname[VLONGFIELD + 1];
  82. } files =
  83. {   TRUE, TRUE, TRUE, TRUE,
  84.     0, TRUE, TRUE, ""
  85. };
  86. MODULE  BPTR           LogFileHandle       = NULL;
  87. MODULE  TEXT           stringholder1[VLONGFIELD + 1],
  88.                        stringholder2[VLONGFIELD + 1],
  89.                        lockstring[VLONGFIELD + 1],
  90.                        liststring[7][VLONGFIELD + 1];
  91.  
  92. MODULE struct ColumnInfo ResultColumnInfo[] =
  93. { { 28,            // WORD   ci_Width
  94.     "Pathname",    // STRPTR ci_Title
  95.     0,             // ULONG  ci_Flags
  96.   },
  97.   { 8,
  98.     "Date",
  99.     0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
  100.           to the right border of the relevant column). */
  101.   },
  102.   { 8,
  103.     "Time",
  104.     0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
  105.           to the right border of the relevant column). */
  106.   },
  107.   { 20,
  108.     "Version",
  109.     0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
  110.           to the right border of the relevant column). */
  111.   },
  112.   { 8,
  113.     "Exp. Date",
  114.     0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
  115.           to the right border of the relevant column). */
  116.   },
  117.   { 8,
  118.     "Exp. Time", // `Exp.' of course stands for `expected'
  119.     0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
  120.           to the right border of the relevant column). */
  121.   },
  122.   { 20,
  123.     "Expected Version",
  124.     0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
  125.           to the right border of the relevant column). */
  126.   },
  127.   { -1, (STRPTR) ~0, -1
  128. } };
  129.  
  130. MODULE struct
  131. {   ULONG red, green, blue, pennumber;
  132. } penn[4] =
  133. {   {0x55555555, 0xFFFFFFFF, 0x55555555, -1}, // green  (OK)        .
  134.     {0xFFFFFFFF, 0x88888888, 0x00000000, -1}, // orange (changed)   !
  135.     {0x55555555, 0xFFFFFFFF, 0xFFFFFFFF, -1}, // cyan   (3rd-party) +
  136.     {0xFFFFFFFF, 0x22222222, 0x22222222, -1}, // red    (missing)   -
  137. };
  138.  
  139. // from rp.c
  140. IMPORT SBYTE               page;
  141. IMPORT struct Window*      MainWindowPtr;
  142. IMPORT TEXT                weekdaystring[LEN_DATSTRING],
  143.                            datestring[LEN_DATSTRING],
  144.                            timestring[LEN_DATSTRING];
  145.  
  146. AGLOBAL void files1(void)
  147. {   struct Hook         Hook10Struct;
  148.     BOOL                inverse;
  149.  
  150.     if (files.log)
  151.     {   inverse = FALSE;
  152.     } else
  153.     {   inverse = TRUE;
  154.     }
  155.     if (!files.pathname[0])
  156.     {   strcpy(files.pathname, "RAM:ReportPlus.log");
  157.     }
  158.  
  159.     /* Create the window object. */
  160.     lockscreen();
  161.     gadtools();
  162.     InitHook(&Hook10Struct, Hook10Func, NULL);
  163.  
  164.     if (!(WinObject[10] =         NewObject(WINDOW_GetClass(), NULL,
  165.     // window
  166.     WA_PubScreen,                 ScreenPtr,
  167.     WA_ScreenTitle,               "Report+",
  168.     WA_Title,                     "Report+: System Files Report",
  169.     WA_Activate,                  TRUE,
  170.     WA_DepthGadget,               TRUE,
  171.     WA_DragBar,                   TRUE,
  172.     WA_CloseGadget,               TRUE,
  173.     WA_SizeGadget,                TRUE,
  174.     WA_IDCMP,                     IDCMP_RAWKEY,
  175.     WINDOW_IDCMPHook,             &Hook10Struct,
  176.     WINDOW_IDCMPHookBits,         IDCMP_RAWKEY,
  177.     WINDOW_MenuStrip,             MenuPtr,
  178.     WINDOW_Position,              WPOS_FULLSCREEN,
  179.     WINDOW_ParentGroup,           files_gadgets[GID_10_LY1] =
  180.                                   NewObject(LAYOUT_GetClass(), NULL,
  181.         // root-layout
  182.         LAYOUT_Orientation,       LAYOUT_ORIENT_VERT,
  183.         LAYOUT_SpaceOuter,        TRUE,
  184.         LAYOUT_DeferLayout,       TRUE,
  185.         LAYOUT_AddChild,          NewObject(LAYOUT_GetClass(), NULL,
  186.             // layout
  187.             LAYOUT_Orientation,   LAYOUT_ORIENT_HORIZ,
  188.             LAYOUT_SpaceOuter,    TRUE,
  189.             LAYOUT_VertAlignment, LALIGN_CENTER,
  190.             LAYOUT_HorizAlignment,LALIGN_CENTER,
  191.             LAYOUT_BevelStyle,    BVS_FIELD,
  192.             LAYOUT_AddChild,      NewObject(LAYOUT_GetClass(), NULL,
  193.                 // layout
  194.                 LAYOUT_Orientation,   LAYOUT_ORIENT_VERT,
  195.                 LAYOUT_SpaceOuter,    TRUE,
  196.                 LAYOUT_VertAlignment, LALIGN_CENTER,
  197.                 LAYOUT_HorizAlignment,LALIGN_LEFT,
  198.                 LAYOUT_BevelStyle,    BVS_FIELD,
  199.                 LAYOUT_AddImage,
  200.                 NewObject
  201.                 (   LABEL_GetClass(),     NULL,
  202.                     LABEL_Text,           "Show:",
  203.                     TAG_END
  204.                 ),
  205.                 CHILD_WeightedHeight,     0,
  206.                 LAYOUT_AddChild,          files_gadgets[GID_10_CB1] =
  207.                 NewObject
  208.                 (   CHECKBOX_GetClass(),  NULL,
  209.                     GA_ID,                GID_10_CB1,
  210.                     GA_RelVerify,         TRUE,
  211.                     CHECKBOX_BackgroundPen, penn[0].pennumber,
  212.                     GA_Text,              "_OK (.)",
  213.                     GA_Selected,          (BOOL) files.show[0],
  214.                     TAG_END
  215.                 ),
  216.                 CHILD_WeightedHeight,     0,
  217.                 LAYOUT_AddChild,          files_gadgets[GID_10_CB2] =
  218.                 NewObject
  219.                 (   CHECKBOX_GetClass(),  NULL,
  220.                     GA_ID,                GID_10_CB2,
  221.                     GA_RelVerify,         TRUE,
  222.                     CHECKBOX_BackgroundPen, penn[1].pennumber,
  223.                     GA_Text,              "_Changed (!)",
  224.                     GA_Selected,          (BOOL) files.show[1],
  225.                     TAG_END
  226.                 ),
  227.                 CHILD_WeightedHeight,     0,
  228.                 LAYOUT_AddChild,          files_gadgets[GID_10_CB3] =
  229.                 NewObject
  230.                 (   CHECKBOX_GetClass(),  NULL,
  231.                     GA_ID,                GID_10_CB3,
  232.                     GA_RelVerify,         TRUE,
  233.                     CHECKBOX_BackgroundPen, penn[2].pennumber,
  234.                     GA_Text,              "_3rd-party (+)",
  235.                     GA_Selected,          (BOOL) files.show[2],
  236.                     TAG_END
  237.                 ),
  238.                 CHILD_WeightedHeight,     0,
  239.                 LAYOUT_AddChild,          files_gadgets[GID_10_CB4] =
  240.                 NewObject
  241.                 (   CHECKBOX_GetClass(),  NULL,
  242.                     GA_ID,                GID_10_CB4,
  243.                     GA_RelVerify,         TRUE,
  244.                     CHECKBOX_BackgroundPen, penn[3].pennumber,
  245.                     GA_Text,              "_Missing (-)",
  246.                     GA_Selected,          (BOOL) files.show[3],
  247.                     TAG_END
  248.                 ),
  249.                 CHILD_WeightedHeight,     0,
  250.                 TAG_END
  251.             ),
  252.             CHILD_WeightedWidth,      0,
  253.             LAYOUT_AddChild,
  254.             NewObject
  255.             (   LAYOUT_GetClass(),    NULL,
  256.                 // layout
  257.                 LAYOUT_Orientation,   LAYOUT_ORIENT_VERT,
  258.                 LAYOUT_SpaceOuter,    TRUE,
  259.                 LAYOUT_VertAlignment, LALIGN_TOP,
  260.                 LAYOUT_HorizAlignment,LALIGN_CENTER,
  261.                 LAYOUT_BevelStyle,    BVS_NONE,
  262.                 LAYOUT_ShrinkWrap,    TRUE,
  263.                 LAYOUT_AddChild,      files_gadgets[GID_10_CB5] =
  264.                 NewObject
  265.                 (   CHECKBOX_GetClass(), NULL,
  266.                     // checkbox
  267.                     GA_ID,            GID_10_CB5,
  268.                     GA_RelVerify,     TRUE,
  269.                     GA_Text,          "Check _versions?",
  270.                     GA_Selected,      (BOOL) files.checkversion,
  271.                 TAG_END),
  272.                 CHILD_WeightedHeight, 0,
  273.                 LAYOUT_AddChild,          NewObject(LAYOUT_GetClass(), NULL,
  274.                     // layout
  275.                     LAYOUT_Orientation,   LAYOUT_ORIENT_HORIZ,
  276.                     LAYOUT_SpaceOuter,    TRUE,
  277.                     LAYOUT_VertAlignment, LALIGN_CENTER,
  278.                     LAYOUT_HorizAlignment,LALIGN_CENTER,
  279.                     LAYOUT_BevelStyle,    BVS_FIELD,
  280.                     LAYOUT_ShrinkWrap,    TRUE,
  281.                     LAYOUT_AddChild,      files_gadgets[GID_10_CB9] =
  282.                     NewObject
  283.                     (   CHECKBOX_GetClass(), NULL,
  284.                         // checkbox
  285.                         GA_ID,                GID_10_CB9,
  286.                         GA_RelVerify,         TRUE,
  287.                         GA_Text,              "_Log to:",
  288.                         GA_Selected,          (BOOL) files.log,
  289.                         TAG_END
  290.                     ),
  291.                     CHILD_WeightedWidth,  0,
  292.                     LAYOUT_AddChild,      files_gadgets[GID_10_ST1] =
  293.                                           NewObject(STRING_GetClass(), NULL,
  294.                         // string        
  295.                         GA_ID,            GID_10_ST1,
  296.                         STRINGA_TextVal,  files.pathname,
  297.                         STRINGA_MinVisible,20,
  298.                         GA_Disabled,      inverse,
  299.                         TAG_END
  300.                     ),
  301.                     LAYOUT_AddChild,      files_gadgets[GID_10_BU1] =
  302.                     NewObject
  303.                     (   NULL, "button.gadget",
  304.                         // button
  305.                         GA_ID,            GID_10_BU1,
  306.                         GA_RelVerify,     TRUE,
  307.                         BUTTON_AutoButton,BAG_POPFILE,
  308.                         GA_Disabled,      inverse,
  309.                         TAG_END
  310.                     ),
  311.                     CHILD_WeightedWidth,  0,
  312.                     TAG_END
  313.                 ),
  314.                 CHILD_WeightedHeight,     0,
  315.  
  316.                 LAYOUT_AddChild,          files_gadgets[GID_10_FG1] =
  317.                 NewObject
  318.                 (   FUELGAUGE_GetClass(), NULL,
  319.                     GA_ID,                GID_10_FG1,
  320.                     GA_Text,              "Ready.",
  321.                     FUELGAUGE_Level,      0,
  322.                     FUELGAUGE_Percent,    FALSE,
  323.                     FUELGAUGE_Justification,FGJ_CENTER,
  324.                 TAG_END),
  325.                 CHILD_WeightedHeight,     0,
  326.                 LAYOUT_AddChild,
  327.                 NewObject
  328.                 (   LAYOUT_GetClass(),    NULL,
  329.                     // layout
  330.                     LAYOUT_Orientation,   LAYOUT_ORIENT_HORIZ,
  331.                     LAYOUT_SpaceOuter,    TRUE,
  332.                     LAYOUT_VertAlignment, LALIGN_CENTER,
  333.                     LAYOUT_HorizAlignment,LALIGN_CENTER,
  334.                     LAYOUT_BevelStyle,    BVS_FIELD,
  335.                     LAYOUT_AddChild,      files_gadgets[GID_10_BU2] =
  336.                     NewObject
  337.                     (   NULL,             "button.gadget",
  338.                         // button
  339.                         GA_ID,            GID_10_BU2,
  340.                         GA_RelVerify,     TRUE,
  341.                         GA_Text,          "_Update",
  342.                         TAG_END
  343.                     ),
  344.                     CHILD_WeightedWidth,  50,
  345.                     LAYOUT_AddChild,      files_gadgets[GID_10_BU3] =
  346.                     NewObject
  347.                     (   NULL,             "button.gadget",
  348.                         // button
  349.                         GA_ID,            GID_10_BU3,
  350.                         GA_RelVerify,     TRUE,
  351.                         GA_Text,          "Stop",
  352.                         GA_Disabled,      TRUE,
  353.                         TAG_END
  354.                     ),
  355.                     CHILD_WeightedWidth,  50,
  356.                     TAG_END
  357.                 ),
  358.                 CHILD_WeightedHeight,     0,
  359.                 TAG_END
  360.             ),
  361.             CHILD_WeightedHeight,         0,
  362.             TAG_END
  363.         ),
  364.         CHILD_WeightedHeight,         0,
  365.         LAYOUT_AddChild,              files_gadgets[GID_10_LB1] =
  366.         NewObject
  367.         (   LISTBROWSER_GetClass(),   NULL,
  368.             GA_ID,                    GID_10_LB1,
  369.             GA_ReadOnly,              TRUE,
  370.             GA_TextAttr,              Gadget.ng_TextAttr,
  371.             LISTBROWSER_Labels,       (ULONG) &EmptyResultList,
  372.             LISTBROWSER_ColumnInfo,   (ULONG) &ResultColumnInfo,
  373.             LISTBROWSER_ColumnTitles, TRUE,
  374.             LISTBROWSER_HorizontalProp,TRUE,
  375.             LISTBROWSER_VirtualWidth, 620 + 620,
  376.             TAG_END
  377.         ),
  378.         CHILD_WeightedHeight,         100,
  379.         TAG_END
  380.     ),
  381.     TAG_END
  382.     )))
  383.     {   rq("Can't create ReAction object(s)!");
  384.     }
  385.     unlockscreen();
  386.     openwindow();
  387.  
  388.     loop();
  389.  
  390.     closewindow();
  391.     files_exit();
  392. }
  393.  
  394. MODULE void updatefiles(void)
  395. {   ULONG  i;
  396.     STRPTR stringptr;
  397.  
  398.     /* Most gadgets are ghosted during the operation. Then their ghosting
  399.     status returns to normal (not necessarily unghosted).
  400.  
  401.         0: Gadget handling.
  402.         1: Set up lists, do the directory examination.
  403.            (For each `source' directory in the `queue', before doing it
  404.            we check for a break. `Break opportunity 1'.)
  405.     At this point we have an empty DirList, and a full FileList, and an
  406.     empty ResultList.
  407.         2: Create the ResultList.
  408.            (For each `source' file in the `queue', before doing it we
  409.            check for a break. `Break opportunity 2'.)
  410.         3: Show results.
  411.  
  412.        DirList: an Exec list of directories found, awaiting examination.
  413.       FileList: an Exec list of files found, awaiting processing.
  414.     ResultList: a listbrowser list of files found, for display.
  415.  
  416.     Apparently the way strings work is that you get told an address where
  417.     the string is stored. This is apparently a pointer into system memory;
  418.     it doesn't need explicit allocation/deallocation by our appliprog. */
  419.  
  420.     if (!(GetAttr
  421.     (   STRINGA_TextVal, files_gadgets[GID_10_ST1], (ULONG *) &stringptr
  422.     )))
  423.     {   rq("Unsupported inquiry!"); // should never happen
  424.     }
  425.     strcpy(files.pathname, stringptr);
  426.  
  427.     SetGadgetAttrs // `Update'
  428.     (   files_gadgets[GID_10_BU2], MainWindowPtr, NULL,
  429.         GA_Disabled, TRUE,
  430.         TAG_END
  431.     );
  432.     SetGadgetAttrs // `Log to file?' (checkbox)
  433.     (   files_gadgets[GID_10_CB9], MainWindowPtr, NULL,
  434.         GA_Disabled, TRUE,
  435.         TAG_END
  436.     );
  437.     /* For some reason, we need to explicitly refresh the checkbox gadget
  438.     visuals here */
  439.     RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB9], MainWindowPtr, NULL);
  440.     SetGadgetAttrs // `Log to file:' (string)
  441.     (   files_gadgets[GID_10_ST1], MainWindowPtr, NULL,
  442.         GA_Disabled, TRUE,
  443.         TAG_END
  444.     );
  445.     SetGadgetAttrs // `Log to file:' (ASL button)
  446.     (   files_gadgets[GID_10_BU1], MainWindowPtr, NULL,
  447.         GA_Disabled, TRUE,
  448.         TAG_END
  449.     );
  450.     for (i = 0; i <= 3; i++)
  451.     {   SetGadgetAttrs // `Show:'
  452.         (   files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL,
  453.             GA_Disabled, TRUE,
  454.             TAG_END
  455.         );
  456.         /* For some reason, we need to explicitly refresh the checkbox gadget
  457.         visuals here */
  458.         RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL);
  459.     }
  460.     SetGadgetAttrs // `Stop'
  461.     (   files_gadgets[GID_10_BU3], MainWindowPtr, NULL,
  462.         GA_Disabled, FALSE,
  463.         TAG_END
  464.     );
  465.     SetGadgetAttrs
  466.     (   files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
  467.         FUELGAUGE_Min,   0,
  468.         FUELGAUGE_Max,   100,
  469.         FUELGAUGE_Level, 16,
  470.         GA_Text,         "Reading volume...",
  471.         TAG_END
  472.     ); // we don't know how many files in advance...
  473.  
  474.     SetGadgetAttrs
  475.     (   files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
  476.         LISTBROWSER_Labels, NULL,
  477.         TAG_END
  478.     );
  479.     SetGadgetAttrs
  480.     (   files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
  481.         LISTBROWSER_Labels, (ULONG) &EmptyResultList,
  482.         TAG_END
  483.     );
  484.     if (ResultNodes)
  485.     {   clearreactionlist(&ResultList);
  486.         ResultNodes = FALSE;
  487.     }
  488.     filesfound = 0;
  489.  
  490.     status = STATUS_BUSY;
  491.     stage1();
  492.     if (status == STATUS_BUSY)
  493.     {   stage2();
  494.     }
  495.     FreeNameNodes(&FileList);
  496.     FreeNameNodes(&FileDateList);
  497.     FreeNameNodes(&FileTimeList);
  498.     if (status == STATUS_BUSY)
  499.     {   stage3();
  500.     }
  501.     status = STATUS_READY;
  502.  
  503.     SetGadgetAttrs // `Update'
  504.     (   files_gadgets[GID_10_BU2], MainWindowPtr, NULL,
  505.         GA_Disabled, FALSE,
  506.         TAG_END
  507.     );
  508.     SetGadgetAttrs // `Log to?' (checkbox)
  509.     (   files_gadgets[GID_10_CB9], MainWindowPtr, NULL,
  510.         GA_Disabled, FALSE,
  511.         TAG_END
  512.     );
  513.     /* For some reason, we need to explicitly refresh the checkbox gadget
  514.     visuals here */
  515.     RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB9], MainWindowPtr, NULL);
  516.     files_updatelog();
  517.     for (i = 0; i <= 7; i++)
  518.     {   SetGadgetAttrs // `Show'
  519.         (   files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL,
  520.             GA_Disabled, FALSE,
  521.             TAG_END
  522.         );
  523.         /* For some reason, we need to explicitly refresh the checkbox gadget
  524.         visuals here */
  525.         RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL);
  526.     }
  527.     SetGadgetAttrs // `Stop'
  528.     (   files_gadgets[GID_10_BU3], MainWindowPtr, NULL,
  529.         GA_Disabled, TRUE,
  530.         TAG_END
  531.     );
  532.     SetGadgetAttrs
  533.     (   files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
  534.         FUELGAUGE_Min,   0,
  535.         FUELGAUGE_Max,   100,
  536.         FUELGAUGE_Level, 0,
  537.         GA_Text,         "Ready.",
  538.         TAG_END
  539.     );
  540. }
  541.  
  542. MODULE void stage1(void)
  543. {   struct NameNode* NodePtr;
  544.  
  545.     NewList(&FileList);
  546.     NewList(&FileDateList);
  547.     NewList(&FileTimeList);
  548.     NewList(&DirList);
  549.     NewList(&ResultList);
  550.     AddNameToTail(&DirList, "");
  551.     // pop all the directories from the work stack, and send them one
  552.     // at a time to files_work() for processing.
  553.     while ((DirList.lh_Head)->ln_Succ) // while the list is non-empty
  554.     {   if (ra_checkbreak() == 1) // we don't yet support completely quitting
  555.         {   status = STATUS_STOPPING;
  556.             stopping("Stopping...");
  557.             break;
  558.         }
  559.  
  560.         /* remove the dir-node from the list, copy its path to
  561.            stringholder1, call files_work, then free the dir-node. */
  562.  
  563.         if (!(NodePtr = (struct NameNode *) RemTail(&DirList)))
  564.         {   rq("RemTail() failed (list is empty!)"); // this should never happen
  565.         }
  566.         strcpy(stringholder1, NodePtr->nn_Data);
  567.         files_work();
  568.         FreeMem(NodePtr, sizeof(struct NameNode));
  569.     }
  570.     FreeNameNodes(&DirList); // Not required unless stopping early (although harmless).
  571. }
  572.  
  573. MODULE void stage2(void)
  574. {   ABOOL            matched;
  575.     ULONG            filesdone = 0,
  576.                      i,
  577.                      length;
  578.     struct NameNode* NodePtr;
  579.     TEXT             filename[VLONGFIELD + 1];
  580.  
  581.     // Now we have the list of files.
  582.     // Everything is already allocated. Don't deallocate in this routine.
  583.  
  584.     if (files.log)
  585.     {   if (!(LogFileHandle = (BPTR) Open(files.pathname, MODE_READWRITE)))
  586.             rq("Can't open file for appending!");
  587.         Seek(LogFileHandle, 0, OFFSET_END);
  588.  
  589.         if (!build)
  590.         {   strcpy(IOBuffer, "AmigaOS system files at ");
  591.             getdate();
  592.             strcat(IOBuffer, timestring);
  593.             strcat(IOBuffer, " on ");
  594.             strcat(IOBuffer, weekdaystring);
  595.             strcat(IOBuffer, " ");
  596.             strcat(IOBuffer, datestring);
  597.             strcat(IOBuffer, ":\n\n");
  598.             if (Write(LogFileHandle, IOBuffer, strlen(IOBuffer)) == -1)
  599.             {   rq("Can't append to file!");
  600.     }   }   }
  601.  
  602.     for (i = 0; i <= FILES; i++)
  603.     {   os[i].matched = FALSE;
  604.     }
  605.  
  606.     /* status is always STATUS_BUSY at this point, because this function is
  607.     not called otherwise. */
  608.  
  609.     SetGadgetAttrs
  610.     (   files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
  611.         FUELGAUGE_Min,   0,
  612.         FUELGAUGE_Max,   filesfound * 3,
  613.         FUELGAUGE_Level, filesfound,
  614.         GA_Text,         "Examining...",
  615.         TAG_END
  616.     );
  617.  
  618.     while ((FileList.lh_Head)->ln_Succ) // while the list is non-empty
  619.     {   if (ra_checkbreak() == 1)
  620.         {   status = STATUS_STOPPING;
  621.             stopping("Stopping...");
  622.             if (files.log)
  623.             {   strcpy(IOBuffer, "Aborted by user!");
  624.                 if (Write(LogFileHandle, IOBuffer, strlen(IOBuffer)) == -1)
  625.                 {   rq("Can't append to file!");
  626.             }   }
  627.             break;
  628.         }
  629.         // assert(status != STATUS_STOPPING);
  630.  
  631.         if (!(filesdone % 50))
  632.         {   SetGadgetAttrs
  633.             (   files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
  634.                 FUELGAUGE_Level, filesfound + filesdone,
  635.                 TAG_END
  636.             );
  637.         }
  638.         filesdone++;
  639.  
  640.         if (!(NodePtr = (struct NameNode *) RemTail(&FileList)))
  641.         {   rq("RemTail() failed (list is empty!)"); // should never happen
  642.         }
  643.         strcpy(stringholder1, NodePtr->nn_Data);
  644.         length = strlen(stringholder1);
  645.         FreeMem(NodePtr, sizeof(struct NameNode));
  646.  
  647.         if (!(NodePtr = (struct NameNode *) RemTail(&FileDateList)))
  648.         {   rq("RemTail() failed (list is empty!)"); // should never happen
  649.         }
  650.         strcpy(datestringholder, NodePtr->nn_Data);
  651.         FreeMem(NodePtr, sizeof(struct NameNode));
  652.  
  653.         if (!(NodePtr = (struct NameNode *) RemTail(&FileTimeList)))
  654.         {   rq("RemTail() failed (list is empty!)"); // should never happen
  655.         }
  656.         strcpy(timestringholder, NodePtr->nn_Data);
  657.         FreeMem(NodePtr, sizeof(struct NameNode));
  658.  
  659.     strcpy(filename, "SYS:");
  660.     strcat(filename, stringholder1);
  661.  
  662.     // now get date of file
  663.  
  664.     if (build)
  665.     {   strcpy(liststring[0], stringholder1);
  666.         strcpy(liststring[1], datestringholder);
  667.         strcpy(liststring[2], timestringholder);
  668.         getversion(filename, liststring[3]);
  669.         dobuffer(3);
  670.     } else
  671.         {   // now we have removed the file from the `queue', and copied its
  672.             // name into stringholder1. Now we check it against each system
  673.             // file.
  674.             matched = FALSE;
  675.             for (i = 0; i <= FILES; i++)
  676.             {   if (!matched && !(stricmp(stringholder1, os[i].pathname)))
  677.                 {   // we have a match
  678.                     matched = os[i].matched = TRUE;
  679.  
  680.                     strcpy(liststring[1], datestringholder);
  681.                     strcpy(liststring[2], timestringholder);
  682.                     strcpy(liststring[4], os[i].thedate);
  683.                     strcpy(liststring[5], os[i].thetime);
  684.  
  685.                     if (files.checkversion)
  686.                     {   getversion(filename, liststring[3]);
  687.                         strcpy(liststring[6], os[i].version);
  688.                     } else
  689.                     {   strcpy(liststring[3], "?");
  690.                         strcpy(liststring[6], "?");
  691.                     }
  692.                     if
  693.                     (   strcmp(os[i].thedate, liststring[1])
  694.                      || strcmp(os[i].thetime, liststring[2])
  695.                      || (files.checkversion && strcmp(os[i].version, liststring[3]))
  696.                     )
  697.                     {   strcpy(liststring[0], "!");
  698.                         strcat(liststring[0], stringholder1);
  699.                         if (files.show[1])
  700.                         {   dobuffer(1);
  701.                     }   }
  702.                     else
  703.                     {   strcpy(liststring[0], ".");
  704.                         strcat(liststring[0], stringholder1);
  705.                         if (files.show[0])
  706.                         {   dobuffer(0);
  707.                     }   }
  708.                     break;
  709.             }   }
  710.             if (files.show[2] && !matched) // third-party
  711.             {   strcpy(liststring[0], "+");
  712.                 strcat(liststring[0], stringholder1);
  713.                 strcpy(liststring[1], datestringholder);
  714.                 strcpy(liststring[2], timestringholder);
  715.  
  716.                 if (files.checkversion)
  717.                 {   getversion(filename, liststring[3]);
  718.                 } else
  719.                 {   strcpy(liststring[3], "?");
  720.                 }
  721.  
  722.                 strcpy(liststring[4], "---");
  723.                 strcpy(liststring[5], "---");
  724.                 strcpy(liststring[6], "?");
  725.                 dobuffer(2);
  726.     }   }   }
  727.  
  728.     if (!build)
  729.     {   // missing files
  730.         if (status == STATUS_BUSY && files.show[3])
  731.         {   SetGadgetAttrs
  732.             (   files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
  733.                 FUELGAUGE_Min,   0,
  734.                 FUELGAUGE_Max,   100,
  735.                 FUELGAUGE_Level, 84,
  736.                 GA_Text,         "Handling missing...",
  737.                 TAG_END
  738.             );
  739.             for (i = 0; i <= FILES; i++)
  740.             {   // For some reason this seems to cause problems
  741.                 if (!(i % 50))
  742.                 {   SetGadgetAttrs
  743.                     (   files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
  744.                         FUELGAUGE_Level, (FILES * 2) + i,
  745.                         TAG_END
  746.                     );
  747.                 }
  748.                 if (!os[i].matched)
  749.                 {   strcpy(liststring[0], "-");
  750.                     strcat(liststring[0], os[i].pathname);
  751.                     strcpy(liststring[1], "---");
  752.                     strcpy(liststring[2], "---");
  753.                     strcpy(liststring[3], "---");
  754.                     strcpy(liststring[4], os[i].thedate);
  755.                     strcpy(liststring[5], os[i].thetime);
  756.                     if (files.checkversion)
  757.                     {    strcpy(liststring[6], os[i].version);
  758.                     } else
  759.                     {    strcpy(liststring[6], "?");
  760.                     }
  761.                     dobuffer(3);
  762.     }   }   }   }
  763.  
  764.     if (LogFileHandle)
  765.     {   Close(LogFileHandle); // Close() doesn't return an error code
  766.         LogFileHandle = NULL;
  767. }   }
  768.  
  769. MODULE void stage3(void)
  770. {   SetGadgetAttrs
  771.     (   files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
  772.         FUELGAUGE_Min,   0,
  773.         FUELGAUGE_Max,   100,
  774.         FUELGAUGE_Level, 0,
  775.         GA_Text,         "Ready.",
  776.         TAG_END
  777.     );
  778.     SetGadgetAttrs
  779.     (   files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
  780.         LISTBROWSER_Labels, NULL,
  781.         TAG_END
  782.     );
  783.     SetGadgetAttrs
  784.     (   files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
  785.         LISTBROWSER_Labels, (ULONG) &ResultList,
  786.         TAG_END
  787.     );
  788. }
  789.  
  790. /* FileNamePtr[]: each of these is a pointer to the allocated memory
  791. area holding the pathname of that file found (excepting "SYS:" portion).
  792. FileNamesAllocated = number of elements of FileNamePtr[]. Or, another way
  793. to think of it, the number of files on the SYS: partition. Element 0 of
  794. the array is not used. */
  795.  
  796. MODULE void files_work(void)
  797. {   BOOL                 more; // BOOL, not ABOOL
  798.     BPTR                 DirHandle; // = NULL;
  799.     struct ExAllControl* eac;       // = NULL;
  800.     struct ExAllData*    ead;
  801.     struct DateTime      DateTime;
  802.  
  803.     DateTime.dat_Format  = FORMAT_DOS;
  804.     DateTime.dat_Flags   = NULL;
  805.     DateTime.dat_StrDay  = NULL;
  806.     DateTime.dat_StrDate = datestring;
  807.     DateTime.dat_StrTime = timestring;
  808.  
  809.     /* Service routine for stage1(). Each call of this routine
  810.     handles one directory from the work stack. This routine is the one
  811.     that actually makes the DOS calls. It pushes any subdirectories
  812.     found onto the stack.
  813.  
  814.     stringholder1 contains the pathname of the directory to examine
  815.         (without "SYS:").
  816.     lockstring contains the pathname of the directory to examine
  817.         (with "SYS:").
  818.     stringholder2 will contain the pathname of each file/dir found
  819.         (with "SYS:"). */
  820.  
  821.     strcpy(lockstring, "SYS:");
  822.     strcat(lockstring, stringholder1);
  823.  
  824.     if (!(DirHandle = (BPTR) Lock(lockstring, ACCESS_READ)))
  825.     {   // Printf("Can't lock %s!\n", lockstring);
  826.         rq("Can't lock directory!");
  827.     }
  828.     if (!(eac = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  829.     {   UnLock(DirHandle);
  830.         DirHandle = NULL;
  831.         rq("Can't allocate DOS object!");
  832.     }
  833.  
  834.     eac->eac_LastKey = 0;
  835.     do
  836.     {   more = ExAll(DirHandle, (struct ExAllData *) EADataPtr, 4096, ED_DATE, eac);
  837.         if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES))
  838.         {   FreeDosObject(DOS_EXALLCONTROL, eac);
  839.             eac = NULL;
  840.             UnLock(DirHandle);
  841.             DirHandle = NULL;
  842.             rq("Can't examine path!"); /* ExAll() failed abnormally */
  843.         }
  844.         if (eac->eac_Entries == 0)
  845.         {   ; /* ExAll() failed normally with no entries */
  846.             continue; /* more is USUALLY zero */
  847.         }
  848.         ead = (struct ExAllData *) EADataPtr;
  849.  
  850.         do
  851.         {   /* use ead here */
  852.  
  853.             strcpy(stringholder2, lockstring);
  854.             if (!AddPart(stringholder2, ead->ed_Name, VLONGFIELD))
  855.             {   FreeDosObject(DOS_EXALLCONTROL, eac);
  856.                 eac = NULL;
  857.                 UnLock(DirHandle);
  858.                 DirHandle = NULL;
  859.                 rq("Can't add filename/dirname to pathname!");
  860.             }
  861.             if (ead->ed_Type == 2) /* +2 is dir, +3 is softlink, -3 is file */
  862.             {   AddNameToTail(&DirList,  &(stringholder2[DRIVELENGTH]));
  863.             } elif (ead->ed_Type == -3) // if it's a file
  864.             {   AddNameToTail(&FileList, &(stringholder2[DRIVELENGTH]));
  865.                 DateTime.dat_Stamp.ds_Days   = ead->ed_Days;
  866.                 DateTime.dat_Stamp.ds_Minute = ead->ed_Mins;
  867.                 DateTime.dat_Stamp.ds_Tick   = ead->ed_Ticks;
  868.                 DateToStr(&DateTime);
  869.                 AddNameToTail(&FileDateList, datestring);
  870.                 AddNameToTail(&FileTimeList, timestring);
  871.                 filesfound++;
  872.             }
  873.  
  874.             /* get next ead */
  875.             ead = ead->ed_Next;
  876.         } while(ead);
  877.     } while(more);
  878.  
  879.     FreeDosObject(DOS_EXALLCONTROL, eac);
  880.     // eac = NULL;
  881.     UnLock(DirHandle);
  882.     // DirHandle = NULL;
  883. }
  884.  
  885. MODULE void dobuffer(ULONG whichpen)
  886. {   struct Node* ListBrowserNodePtr;
  887.     TEXT         codestring[VLONGFIELD + 1], spaces[LONGFIELD + 1];
  888.     SLONG        gap;
  889.     ULONG        i;
  890.  
  891.     /* Service routine for stage2(). */
  892.  
  893.     if (!(ListBrowserNodePtr = AllocListBrowserNode
  894.     (   7,              // columns,
  895.         LBNA_Column,    0,
  896.             LBNA_Flags,     LBFLG_CUSTOMPENS,
  897.             LBNCA_FGPen,    BLACK,
  898.             LBNCA_BGPen,    penn[whichpen].pennumber,
  899.             LBNCA_CopyText, TRUE,
  900.             LBNCA_Text,     &liststring[0][1],
  901.         LBNA_Column,    1,
  902.             LBNA_Flags,     LBFLG_CUSTOMPENS,
  903.             LBNCA_FGPen,    BLACK,
  904.             LBNCA_BGPen,    penn[whichpen].pennumber,
  905.             LBNCA_CopyText, TRUE,
  906.             LBNCA_Text,     liststring[1],
  907.         LBNA_Column,    2,
  908.             LBNA_Flags,     LBFLG_CUSTOMPENS,
  909.             LBNCA_FGPen,    BLACK,
  910.             LBNCA_BGPen,    penn[whichpen].pennumber,
  911.             LBNCA_CopyText, TRUE,
  912.             LBNCA_Text,     liststring[2],
  913.         LBNA_Column,    3,
  914.             LBNA_Flags,     LBFLG_CUSTOMPENS,
  915.             LBNCA_FGPen,    BLACK,
  916.             LBNCA_BGPen,    penn[whichpen].pennumber,
  917.             LBNCA_CopyText, TRUE,
  918.             LBNCA_Text,     liststring[3],
  919.         LBNA_Column,    4,
  920.             LBNA_Flags,     LBFLG_CUSTOMPENS,
  921.             LBNCA_FGPen,    BLACK,
  922.             LBNCA_BGPen,    penn[whichpen].pennumber,
  923.             LBNCA_CopyText, TRUE,
  924.             LBNCA_Text,     liststring[4],
  925.         LBNA_Column,    5,
  926.             LBNA_Flags,     LBFLG_CUSTOMPENS,
  927.             LBNCA_FGPen,    BLACK,
  928.             LBNCA_BGPen,    penn[whichpen].pennumber,
  929.             LBNCA_CopyText, TRUE,
  930.             LBNCA_Text,     liststring[5],
  931.         LBNA_Column,    6,
  932.             LBNA_Flags,     LBFLG_CUSTOMPENS,
  933.             LBNCA_FGPen,    BLACK,
  934.             LBNCA_BGPen,    penn[whichpen].pennumber,
  935.             LBNCA_CopyText, TRUE,
  936.             LBNCA_Text,     liststring[6],
  937.     TAG_END)))
  938.     {   rq("Can't create ReAction listbrowser.gadget node(s)!");
  939.     }
  940.     AddTail(&ResultList, ListBrowserNodePtr); // AddTail() has no return code
  941.     ResultNodes = TRUE;
  942.  
  943.     if (files.log)
  944.     {   if (build)
  945.         {   strcpy(codestring, "{\"");    // {"
  946.             strcat(codestring, liststring[0]);
  947.             strcat(codestring, "\", \""); // ", "
  948.             strcat(codestring, liststring[1]);
  949.             strcat(codestring, "\", \""); // ", "
  950.             strcat(codestring, liststring[2]);
  951.             strcat(codestring, "\", \""); // ", "
  952.             strcat(codestring, liststring[3]);
  953.             strcat(codestring, "\"},\n"); // "},
  954.         } else
  955.         {   strcpy(codestring, liststring[0]);
  956.             if (strlen(liststring[0]) >= 49)
  957.             {   strcat(codestring, "\n"
  958.                 "                                                  "); // 50 spaces
  959.             } else
  960.             {   gap = 50 - strlen(liststring[0]);
  961.                 for (i = 0; i < gap; i++)
  962.                 {   spaces[i] = ' ';
  963.                 }
  964.                 spaces[gap] = 0;
  965.                 strcat(codestring, spaces);
  966.             }
  967.             strcat(codestring, liststring[1]);
  968.             gap = 10 - strlen(liststring[1]);
  969.             if (gap >= 1)
  970.             {   for (i = 0; i < gap; i++)
  971.                 {   spaces[i] = ' ';
  972.                 }
  973.                 spaces[gap] = 0;
  974.                 strcat(codestring, spaces);
  975.             }
  976.             strcat(codestring, liststring[2]);
  977.             gap = 9 - strlen(liststring[2]);
  978.             if (gap >= 1)
  979.             {   for (i = 0; i < gap; i++)
  980.                 {   spaces[i] = ' ';
  981.                 }
  982.                 spaces[gap] = 0;
  983.                 strcat(codestring, spaces);
  984.             }
  985.             strcat(codestring, liststring[3]);
  986.             strcat(codestring, "\n"
  987.             "                                                  "); // 50 spaces
  988.             strcat(codestring, liststring[4]);
  989.             gap = 10 - strlen(liststring[4]);
  990.             if (gap >= 1)
  991.             {   for (i = 0; i < gap; i++)
  992.                 {   spaces[i] = ' ';
  993.                 }
  994.                 spaces[gap] = 0;
  995.                 strcat(codestring, spaces);
  996.             }
  997.             strcat(codestring, liststring[5]);
  998.             gap = 9 - strlen(liststring[5]);
  999.             if (gap >= 1)
  1000.             {   for (i = 0; i < gap; i++)
  1001.                 {   spaces[i] = ' ';
  1002.                 }
  1003.                 spaces[gap] = 0;
  1004.                 strcat(codestring, spaces);
  1005.             }
  1006.             strcat(codestring, liststring[6]);
  1007.             strcat(codestring, "\n");
  1008.         }
  1009.         if (Write(LogFileHandle, codestring, strlen(codestring)) == -1)
  1010.         {   rq("Can't append to file!");
  1011. }   }   }
  1012.  
  1013. AGLOBAL void files_init(void)
  1014. {   ULONG        i;
  1015.     struct Node* ListBrowserNodePtr;
  1016.  
  1017.     lockscreen();
  1018.     for (i = 0; i <= 3; i++)
  1019.     {   penn[i].pennumber = FindColor
  1020.         (   ScreenPtr->ViewPort.ColorMap,
  1021.             penn[i].red,
  1022.             penn[i].green,
  1023.             penn[i].blue,
  1024.             -1
  1025.         );
  1026.     }
  1027.     unlockscreen();
  1028.     if (!(files.pathname[0]))
  1029.     {   strcpy(files.pathname, "RAM:ReportPlus.log");
  1030.     }
  1031.  
  1032.     NewList(&ResultList);
  1033.     NewList(&EmptyResultList);
  1034.     if (!(ListBrowserNodePtr = AllocListBrowserNode
  1035.     (   7,           // columns
  1036.         /* LBNCA_ tags are those that apply to the specific column. */
  1037.         LBNA_Column, 0,
  1038.         LBNA_Column, 1,
  1039.         LBNA_Column, 2,
  1040.         LBNA_Column, 3,
  1041.         LBNA_Column, 4,
  1042.         LBNA_Column, 5,
  1043.         LBNA_Column, 6,
  1044.         TAG_END
  1045.     )))
  1046.     {   rq("Can't create ReAction listbrowser.gadget node(s)!");
  1047.     }
  1048.     AddTail(&EmptyResultList, ListBrowserNodePtr); // AddTail() has no return code
  1049.     EmptyResultNodes = TRUE;
  1050. }
  1051.  
  1052. AGLOBAL void files_exit(void)
  1053. {   // The window should be closed before calling this.
  1054.  
  1055.     if (ResultNodes)
  1056.     {   clearreactionlist(&ResultList);
  1057.         ResultNodes = FALSE;
  1058.     }
  1059.     if (LogFileHandle)
  1060.     {   Close(LogFileHandle); // Close() doesn't return an error code
  1061.         LogFileHandle = NULL;
  1062. }   }
  1063.  
  1064. AGLOBAL void files_die(void)
  1065. {   ULONG i;
  1066.  
  1067.     IOBuffer[23] = (UBYTE) files.log;
  1068.     for (i = 0; i <= 3; i++)
  1069.     {   IOBuffer[i + 8] = (UBYTE) files.show[i];
  1070.     }
  1071.     IOBuffer[7] = (UBYTE) files.checkversion;
  1072. }
  1073.  
  1074. AGLOBAL void files_config(void)
  1075. {   UBYTE i;
  1076.  
  1077.     files.log = (ULONG) IOBuffer[23];
  1078.  
  1079.     for (i = 0; i <= 3; i++)
  1080.     {   files.show[i] = (ULONG) IOBuffer[i + 8];
  1081.     }
  1082.     files.checkversion = (ULONG) IOBuffer[7];
  1083. }
  1084.  
  1085. AGLOBAL void files_loop(ULONG gid)
  1086. {   STRPTR stringptr;
  1087.  
  1088.     switch (gid)
  1089.     {
  1090.     case GID_10_CB1:
  1091.         if (!(GetAttr
  1092.         (   GA_Selected, files_gadgets[GID_10_CB1], (ULONG *) &files.show[0]
  1093.         )))
  1094.         {   rq("Unsupported inquiry!"); // should never happen
  1095.         }
  1096.     break;
  1097.     case GID_10_CB2:
  1098.         if (!(GetAttr
  1099.         (   GA_Selected, files_gadgets[GID_10_CB2], (ULONG *) &(files.show[1])
  1100.         )))
  1101.         {   rq("Unsupported inquiry!"); // should never happen
  1102.         }
  1103.     break;
  1104.     case GID_10_CB3:
  1105.         if (!(GetAttr
  1106.         (   GA_Selected, files_gadgets[GID_10_CB3], (ULONG *) &files.show[2]
  1107.         )))
  1108.         {   rq("Unsupported inquiry!"); // should never happen
  1109.         }
  1110.     break;
  1111.     case GID_10_CB4:
  1112.         if (!(GetAttr
  1113.         (   GA_Selected, files_gadgets[GID_10_CB4], (ULONG *) &files.show[3]
  1114.         )))                                                                    
  1115.         {   rq("Unsupported inquiry!"); // should never happen
  1116.         }
  1117.     break;
  1118.     case GID_10_CB5:
  1119.         if (!(GetAttr
  1120.         (   GA_Selected, files_gadgets[GID_10_CB5], (ULONG *) &files.checkversion
  1121.         )))                                                                    
  1122.         {   rq("Unsupported inquiry!"); // should never happen
  1123.         }
  1124.     break;
  1125.     case GID_10_ST1:
  1126.         if (!(GetAttr
  1127.         (   STRINGA_TextVal, files_gadgets[GID_10_ST1], (ULONG *) &stringptr
  1128.         )))
  1129.         {   rq("Unsupported inquiry!"); // should never happen
  1130.         }
  1131.         strcpy(files.pathname, stringptr);
  1132.     break;
  1133.     case GID_10_BU1:
  1134.         if (asl("~(#?.info)"))
  1135.         {   strcpy(files.pathname, aslresult);
  1136.             SetGadgetAttrs
  1137.             (   files_gadgets[GID_10_ST1], MainWindowPtr, NULL,
  1138.                 STRINGA_TextVal, files.pathname,
  1139.                 TAG_END
  1140.            );
  1141.         }
  1142.     break;
  1143.     case GID_10_BU2:
  1144.         updatefiles();
  1145.     break;
  1146.     case GID_10_CB9:
  1147.         if (!(GetAttr
  1148.         (   GA_Selected, files_gadgets[GID_10_CB9], &files.log
  1149.         )))
  1150.         {   rq("Unsupported inquiry!"); // should never happen
  1151.         }
  1152.         files_updatelog();
  1153.         if (files.log)
  1154.         {   ActivateLayoutGadget(files_gadgets[GID_10_LY1], MainWindowPtr, NULL, (Object) files_gadgets[GID_10_ST1]);
  1155.         }
  1156.     break;
  1157.     default:
  1158.     break;
  1159. }   }
  1160.  
  1161. AGLOBAL ULONG Hook10Func(struct Hook *h, VOID *o, VOID *msg)
  1162. {   /* "When the hook is called, the data argument points to the 
  1163.     window object and message argument to the IntuiMessage." */
  1164.  
  1165.     UWORD code, qual;
  1166.     ULONG scroll = 0;
  1167.  
  1168.     geta4(); // wait till here before doing anything
  1169.  
  1170.     code = ((struct IntuiMessage *) msg)->Code;
  1171.     qual = ((struct IntuiMessage *) msg)->Qualifier;
  1172.  
  1173.     switch(code)
  1174.     {
  1175.     case SCAN_HELP:
  1176.         if (status == STATUS_READY)
  1177.         {   helpabout();
  1178.         }
  1179.     break;
  1180.     case SCAN_ESCAPE:
  1181.         if (status == STATUS_READY)
  1182.         {   if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  1183.             {   cleanexit(EXIT_SUCCESS);
  1184.             } else page = 0;
  1185.         } else
  1186.         {   // assert(status == STATUS_BUSY);
  1187.             status = STATUS_STOPPING;
  1188.         }
  1189.     break;
  1190.     case SCAN_UP:
  1191.         if (qual & IEQUALIFIER_CONTROL)
  1192.         {   scroll = LBP_TOP;
  1193.         } elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
  1194.         {   scroll = LBP_PAGEUP;
  1195.         } else scroll = LBP_LINEUP;
  1196.     break;
  1197.     case SCAN_DOWN:
  1198.         if (qual & IEQUALIFIER_CONTROL)
  1199.         {   scroll = LBP_BOTTOM;
  1200.         } elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
  1201.         {   scroll = LBP_PAGEDOWN;
  1202.         } else scroll = LBP_LINEDOWN;
  1203.     break;
  1204.     default:
  1205.     break;
  1206.     }
  1207.  
  1208.     if (code == SCAN_UP || code == SCAN_DOWN)
  1209.     {   SetGadgetAttrs
  1210.         (   files_gadgets[GID_10_LB1],    // pointer to gadget
  1211.             MainWindowPtr,                // pointer to window (not window object!)
  1212.             NULL,                         // pointer to requester
  1213.             LISTBROWSER_Position, scroll, // tags
  1214.             TAG_DONE                      // done
  1215.         );
  1216.     }
  1217.  
  1218.     return(1);
  1219. }
  1220.  
  1221. MODULE void stopping(STRPTR status)
  1222. {   SetGadgetAttrs
  1223.     (   files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
  1224.         GA_Text, status,
  1225.         TAG_END
  1226.     );
  1227.     SetGadgetAttrs // `Stop'
  1228.     (   files_gadgets[GID_10_BU3], MainWindowPtr, NULL,
  1229.         GA_Disabled, TRUE,
  1230.         TAG_END
  1231.     );
  1232. }
  1233.  
  1234. MODULE void files_updatelog(void)
  1235. {   BOOL inverse;
  1236.  
  1237.     if (files.log)
  1238.     {   inverse = FALSE;
  1239.     } else
  1240.     {   inverse = TRUE;
  1241.     }
  1242.  
  1243.     SetGadgetAttrs // `Log to file:' (string)
  1244.     (   files_gadgets[GID_10_ST1], MainWindowPtr, NULL,
  1245.         GA_Disabled, inverse,
  1246.         TAG_END
  1247.     );
  1248.     /* For some reason, we need to explicitly refresh the string gadget
  1249.     visuals here */
  1250.     RefreshGadgets((struct Gadget *) files_gadgets[GID_10_ST1], MainWindowPtr, NULL);
  1251.  
  1252.     SetGadgetAttrs // `Log to file:' (ASL button)
  1253.     (   files_gadgets[GID_10_BU1], MainWindowPtr, NULL,
  1254.         GA_Disabled, inverse,
  1255.         TAG_END
  1256.     );
  1257. }
  1258.  
  1259.